<?php
/**
 * Copyright (c) 2020
 * 摘    要：
 * 作    者：san
 * 修改日期：2020.03.30
 */

namespace App\Service;

use App\Model\User;
use App\Model\WorkSpaceUser;
use ErrorException;
use Exception;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Model;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\Context;

class UserService extends BaseService
{
    /**
     * UserService constructor.
     */
    public function __construct()
    {
        parent::__construct();

        $this->redis = redis();
    }

    /**
     * 用户登录
     *
     * @param $data
     * @throws ErrorException
     * @return array
     */
    public function login($data)
    {
        $user = User::findByCondition(['username' => $data['account']]);

        if (!$user) {
            throw new ErrorException(t("message.12041"));
        }
        //校验密码
        if (!password_verify($data['password'], $user->password)) {
            throw new ErrorException(t('message.12042'));
        }
        $token = $this->redis->get(User::USER_SESSION_KEY . $user->user_id);
        if (!$token) {
            $token = $this->_flashUserToken($user);
        }
        return ['token' => $token];
    }

    /**
     * 用户退出
     *
     * @param $token
     * @return bool
     */
    public function logout($token)
    {
        $id = $this->redis->get(User::USER_SESSION_KEY . $token);
        $this->redis->del(User::USER_SESSION_KEY . $token);
        $this->redis->del(User::USER_SESSION_KEY . $id);

        return true;
    }

    /**
     * 用户列表
     *
     * @param $page
     * @param $pageSize
     * @param $condition
     * @return array
     */
    public function list($page, $pageSize, $condition)
    {
        $fields = [
            'user_id',
            'username',
            'nick_name as name',
            'avatar',
            'email',
            'created_at'
        ];

        $query = User::query()
            ->select($fields)
            ->where('user_id', '<>', 1);

        if ($condition) {
            $query = $query->where($condition);
        }

        $count  = $query->count();
        $result = $query->limit($pageSize)->offset(($page - 1) * $pageSize)
            ->orderBy('user_id', 'desc')
            ->get();

        return [
            'list'  => $result,
            'total' => $count,
        ];
    }

    /**
     * @param $data
     * @throws ErrorException
     */
    public function add($data)
    {
        $hasOne = User::query(true)->where('username', $data['username'])->first();
        if ($hasOne) throw new ErrorException(t('message.12043'));

        $data['password'] = password_hash(User::DEFAULT_PASSWORD, PASSWORD_DEFAULT);
        $res              = Db::table('users')->insert($data);
        if (!$res) throw new ErrorException(t('message.12002'));
    }

    /**
     * @param $data
     * @throws ErrorException
     */
    public function edit($data)
    {
        $id       = $data['id'];
        $nickName = $data['nick_name'];
        $email    = $data['email'];
        $user     = $this->_checkUserExits($id);

        $user->nick_name = $nickName;
        $user->email     = $email;
        $res             = $user->save();

        if (!$res) throw new ErrorException(t('message.12002'));
    }

    /**
     * 删除用户
     *
     * @param $id
     * @throws ErrorException
     * @throws Exception
     * @return bool|int|mixed|null
     */
    public function delete($id)
    {
        $user = $this->_checkUserExits($id);

        $res = $user->delete();
        if (!$res) throw new ErrorException(t('message.12002'));
    }

    /**
     * @param $id
     * @throws ErrorException
     * @return Builder|Builder[]|Collection|Model|null
     */
    private function _checkUserExits($id)
    {
        $user = User::query(true)->find($id);
        if (!$user) throw new ErrorException(t('message.12041'));

        return $user;
    }

    /**
     * 刷新token
     *
     * @param User $user
     * @return string
     */
    private function _flashUserToken(User $user)
    {
        $token = generateToken();
        $this->redis->set(User::USER_SESSION_KEY . $user->user_id, $token, User::TOKEN_CACHE_TTL);
        $this->redis->set(User::USER_SESSION_KEY . $token, $user->user_id, User::TOKEN_CACHE_TTL);
        //保存token
        $user->remember_token = $token;
        $user->save();

        return $token;
    }

    /**
     * token检测
     *
     * @param $token
     * @throws ErrorException
     * @return bool|mixed|string
     */
    public function tokenCheck($token)
    {
        $uuid = $this->redis->get(User::USER_SESSION_KEY . $token);

        if (!$uuid) {
            throw new ErrorException(t('message.12045'), 401);
        }

        return $uuid;
    }

    /**
     * 用户基本信息
     *
     * @throws Exception
     * @return array
     */
    public function info()
    {
        $user = Context::get('user');

        if (!$user) {
            throw new \ErrorException(t('message.12069'));
        }

        // 1、基本信息 昵称，ID，头像，邮箱，角色，所属项目组
        if ($user->user_id !== 1) {
            $wUser = WorkSpaceUser::query(true)
                ->select(['r.name as role_name', 'w.name as workspace_name'])
                ->leftJoin('workspace as w', 'w.id', '=', 'workspace_user.workspace_id')
                ->leftJoin('roles as r', 'r.id', '=', 'workspace_user.role_id')
                ->where('workspace_user.user_id', $user->user_id)->limit(1)->get()->toArray();

            return [
                'name'       => $user->nick_name,
                'avatar'     => $user->avatar,
                'user_id'    => $user->user_id,
                'email'      => $user->email,
                'created_at' => date("Y-m-d", strtotime($user->created_at)),
                'access'     => $this->_getUserPermissions($user),
                'role'       => $wUser[0]['role_name'] ?? '',
                'workspace'  => $wUser[0]['workspace_name'] ?? '',
            ];
        } else {
            return [
                'name'       => $user->nick_name,
                'avatar'     => $user->avatar,
                'user_id'    => $user->user_id,
                'email'      => $user->email,
                'created_at' => date("Y-m-d", strtotime($user->created_at)),
                'access'     => $this->_getUserPermissions($user),
                'role'       => '管理员',
                'workspace'  => '运维组',
            ];
        }
    }

    /**
     * 获取用户权限
     *
     * @param User $user
     * @throws Exception
     * @return array
     */
    public function _getUserPermissions(User $user)
    {
        $permission = $user->getAllPermissions();
        $tmp        = [];

        if ($permission) {
            foreach ($permission as $value) {
                $tmp[] = $value['name'];
            }
        }

        return $tmp;
    }

    /**
     * @param $token
     * @param $nickName
     * @param $password
     * @return int
     */
    public function changeInfo($token, $nickName = '', $password = '')
    {
        $uuid = Context::get('user')->user_id;
        $data = [];

        if ($nickName) {
            $data = ['nick_name' => $nickName];
        }

        if ($password) {
            $data['password'] = password_hash($password, PASSWORD_DEFAULT);
        }

        if ($data) {
            $this->logout($token);
            return User::query(true)->where('user_id', $uuid)->update($data);
        }

        return true;
    }
}